package com.vincent.videocompress;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.hw.videoprocessor.VideoProcessor;
import com.hw.videoprocessor.util.CL;
import com.hw.videoprocessor.util.VideoMultiStepProgress;
import com.hw.videoprocessor.util.VideoProgressListener;
import com.vincent.videocompressor.VideoCompress;
import com.vincent.videocompressor.VideoUtil;

import java.io.File;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 压缩不失真的分辨率参考值
 * <p>
 * 144P  （192×144，20帧/秒），4：3，录制一分钟大约1MB；
 * 240p（320×240，20帧/秒），4：3，录制一分钟大约3MB；
 * 360P （480×360，20帧/秒） ，4：3，录制一分钟大约7MB；
 * 480P （640×480，20帧/秒），4：3，录制一分钟大约12MB； 每帧 83886 bit
 * 720P （1280×720，30帧/秒）  ， 16:9，录制一分钟大约35MB； 每帧139810 bit
 * 1080P （1920×1080，30帧/秒） ，16:9 ， 录制一分钟大约80MB。
 * 2K （1152 × 2048）
 * 4K（2304 × 4096）
 */
public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_FOR_VIDEO_FILE = 1000;
    private TextView tv_input, tv_output, tv_indicator, tv_progress;
    private SeekBar sb_size;
    private TextView tv_size;
    private CheckBox size_baseline; // 分辨率的以基准，默认为高
    private SeekBar sb_bitrate;
    private SeekBar sb_framerate;
    private TextView tv_bitrate;
    private TextView tv_framerate;
    private String outputDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();

    private String inputPath;
    private String outputPath;

    private ProgressBar pb_compress;

    private long startTime, endTime;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1002);
        }
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1002);
        }
        CL.setLogEnable(true);
    }

    private int oriHeight;
    private int resultHeight;
    private int oriWidth;
    private int resultWidth;
    private int oriBitrate;
    private int resultBitrate;
    private int oriFrameRate;
    private int resultFrameRate;
    private float videTime;
    private double maxBitrate;
    private Button btn_compress;

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        sb_size = findViewById(R.id.sb_size);
        tv_size = findViewById(R.id.tv_size);
        //  size_baseline = findViewById(R.id.ck_size_baseline);
        sb_bitrate = findViewById(R.id.sb_bitrate);
        tv_bitrate = findViewById(R.id.tv_bitrate);

        sb_framerate = findViewById(R.id.sb_framerate);
        tv_framerate = findViewById(R.id.tv_framerate);
        sb_size.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                resultWidth = oriWidth * progress / 100;
                resultHeight = oriHeight * progress / 100;
                tv_size.setText("分辨率:" + resultWidth + "x" + resultHeight);
                //  maxBitrate = (resultWidth * resultHeight) / (oriHeight * oriWidth) * oriBitrate ;
                maxBitrate = (progress / 100.00) * (progress / 100.00) * oriBitrate;
                if (resultBitrate > maxBitrate) {
                    resultBitrate = (int) maxBitrate;
                    tv_bitrate.setText("码率:" + resultBitrate + "    预计压缩后大小:" + videTime * resultBitrate / 8 / 1024 / 1024 + "MB");
                    sb_bitrate.setProgress((int) (maxBitrate * 100 / oriBitrate));
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
              /*  int progress = seekBar.getProgress();
                oriWidth  = oriWidth * progress / 100;
                oriHeight = oriHeight * progress / 100;
                tv_size.setText("分辨率:" + oriWidth + "x" + oriHeight);*/
            }
        });
        sb_bitrate.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(final SeekBar seekBar, int progress, boolean b) {
                int newBitrate = oriBitrate * progress / 100;
                if (newBitrate > maxBitrate) {
                    seekBar.setEnabled(false);
                    Toast.makeText(MainActivity.this, "当前分辨率下,最大码率为" + (int) (maxBitrate), Toast.LENGTH_LONG).show();
                    seekBar.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            seekBar.setEnabled(true);
                        }
                    }, 2000);
                    return;
                }
                resultBitrate = newBitrate;
                tv_bitrate.setText("码率:" + resultBitrate + "    预计压缩后大小:" + videTime * resultBitrate / 8 / 1024 / 1024 + "MB");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                seekBar.setEnabled(true);
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                seekBar.setEnabled(true);
              /*  int progress = seekBar.getProgress();
                oriBitrate = oriBitrate * progress / 100;
                tv_bitrate.setText("码率:" + oriBitrate + "    预计压缩后大小:" + videTime*oriBitrate/8/1024/1024+"MB");
*/
            }
        });

        sb_framerate.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                int newFrameRate = oriFrameRate * progress / 100;
                resultFrameRate = newFrameRate;
                tv_framerate.setText("帧率:" + resultFrameRate +"/s");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        initView();
    }
   private long lastClickTimeMs;// 上次点击压缩键的时间
    private void initView() {
        Button btn_select = (Button) findViewById(R.id.btn_select);
        btn_select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                /* 开启Pictures画面Type设定为image */
                //intent.setType("video/*;image/*");
                //intent.setType("audio/*"); //选择音频
                intent.setType("video/*"); //选择视频 （mp4 3gp 是android支持的视频格式）
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, REQUEST_FOR_VIDEO_FILE);
            }
        });

        btn_compress = (Button) findViewById(R.id.btn_compress);
        btn_compress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (view.getTag() == null) {
                    final String destPath = tv_output.getText().toString() + File.separator + "VID_" + new SimpleDateFormat("yyyyMMdd_HHmmss", getLocale()).format(new Date()) + ".mp4";
                    compress2(destPath);
                } else {
                    long curTime = System.currentTimeMillis();
                    if (curTime - lastClickTimeMs > 2000) {
                        Toast.makeText(MainActivity.this, "再次点击,提前结束压缩", Toast.LENGTH_LONG).show();
                        lastClickTimeMs = curTime;
                        return;
                    }

                    if (processor != null) processor.interrupt();
                    view.setTag(null);
                    btn_compress.setText("开始压缩");
                }
            }
        });

        tv_input = (TextView) findViewById(R.id.tv_input);
        tv_output = (TextView) findViewById(R.id.tv_output);
        tv_output.setText(outputDir);
        tv_indicator = (TextView) findViewById(R.id.tv_indicator);
        tv_progress = (TextView) findViewById(R.id.tv_progress);

        pb_compress = (ProgressBar) findViewById(R.id.pb_compress);
    }

    private Uri inputUri;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_FOR_VIDEO_FILE && resultCode == RESULT_OK) {
            if (data != null && data.getData() != null) {
//                inputPath = data.getData().getPath();
//                tv_input.setText(inputPath);
                try {
                    inputUri = data.getData();
                    inputPath = Util.getFilePath(this, data.getData());
                    if (TextUtils.isEmpty(inputPath)) {
                        inputPath = data.getData().getPath();
                        inputPath = inputPath.startsWith("/root") ? inputPath.replace("/root", "") : inputPath;
                    }
                    tv_input.setText(inputPath);
                    tv_indicator.setText("视频信息 :" + "\n" + getVideoInfo(inputPath) + "\n");
                    tv_size.setText("分辨率:" + oriWidth + "x" + oriHeight);
                    sb_size.setProgress(100);
                    resultBitrate = oriBitrate;
                    resultHeight = oriHeight;
                    resultWidth = oriWidth;
                    resultFrameRate = oriFrameRate;
                    tv_bitrate.setText("码率:" + resultBitrate);
                    sb_bitrate.setProgress(100);
                    tv_framerate.setText("帧率:" + resultFrameRate+"/s");
                    sb_framerate.setProgress(100);
                    //   pb_compress.setVisibility(View.VISIBLE);
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }

//                inputPath = "/storage/emulated/0/DCIM/Camera/VID_20170522_172417.mp4"; // 图片文件路径
//                tv_input.setText(inputPath);// /storage/emulated/0/DCIM/Camera/VID_20170522_172417.mp4
            }
        }
    }

    private void compress1(final String destPath) {
        VideoCompress.compressVideoCustom(tv_input.getText().toString(), destPath, resultWidth, resultHeight, resultBitrate, new VideoCompress.CompressListener() {
            @Override
            public void onStart() {
                tv_indicator.setText("压缩中..." + "\n"
                        + "开始时间: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n" + getVideoInfo(inputPath) + "\n");
                pb_compress.setVisibility(View.VISIBLE);
                startTime = System.currentTimeMillis();
                Util.writeFile(MainActivity.this, "Start at: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()));
            }

            @Override
            public void onSuccess() {
                String previous = tv_indicator.getText().toString();

                tv_indicator.setText(previous + "\n"
                        + "压缩成功" + "\n"
                        + "结束时间: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n" + getVideoInfo(new File(destPath).length() > 0 ? destPath : inputPath) + "\n");
                pb_compress.setVisibility(View.INVISIBLE);
                endTime = System.currentTimeMillis();
                Util.writeFile(MainActivity.this, "End at: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n");
                Util.writeFile(MainActivity.this, "Total: " + ((endTime - startTime) / 1000) + "s" + "\n");
                Util.writeFile(MainActivity.this);
            }

            @Override
            public void onFail() {
                tv_indicator.setText("Compress Failed!");
                pb_compress.setVisibility(View.INVISIBLE);
                endTime = System.currentTimeMillis();
                Util.writeFile(MainActivity.this, "压缩失败!!!" + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()));
            }

            @Override
            public void onProgress(float percent) {
                DecimalFormat df = new DecimalFormat("##0.000000");
                String result = df.format(percent);
                tv_progress.setText(result + "%");
                Log.e("test", "进度 " + result + "%");
            }
        });
    }

    private VideoProcessor.Processor processor;

    private void compress2(final String destPath) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    processor = VideoProcessor.processor(MainActivity.this)
                            .input(inputUri)
                            .output(destPath)
                            .outWidth(resultWidth)
                            .outHeight(resultHeight)
                            .bitrate(resultBitrate)
                            .frameRate(resultFrameRate)
                            .progressListener(new VideoProgressListener() {
                                @Override
                                public void onProgress(final float percent) {
                                    tv_progress.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            DecimalFormat df = new DecimalFormat("##0.000000");
                                            String result = df.format(percent * 100);
                                            tv_progress.setText(result + "%");
                                            Log.e("test", "进度 " + result + "%");
                                        }
                                    });
                                }
                            });
                    processor.process();

                    tv_indicator.post(new Runnable() {
                        @Override
                        public void run() {
                            String previous = tv_indicator.getText().toString();
                            tv_indicator.setText(previous + "\n"
                                    + "压缩成功" + "\n"
                                    + "结束时间: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n" + getVideoInfo(new File(destPath).length() > 0 ? destPath : inputPath) + "\n");
                            pb_compress.setVisibility(View.INVISIBLE);
                            endTime = System.currentTimeMillis();
                            btn_compress.setText("开始压缩");
                            btn_compress.setTag(null);
                            Util.writeFile(MainActivity.this, "End at: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n");
                            Util.writeFile(MainActivity.this, "Total: " + ((endTime - startTime) / 1000) + "s" + "\n");
                            Util.writeFile(MainActivity.this);
                        }
                    });
                } catch (Exception e) {
                    tv_indicator.post(new Runnable() {
                        @Override
                        public void run() {
                            tv_indicator.setText("Compress Failed!");
                            pb_compress.setVisibility(View.INVISIBLE);
                            endTime = System.currentTimeMillis();
                            Util.writeFile(MainActivity.this, "压缩失败!!!" + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()));
                        }
                    });
                    e.printStackTrace();
                }

            }
        }).start();
        btn_compress.setText("结束压缩");
        btn_compress.setTag(new Object());
        tv_indicator.setText("压缩中..." + "\n"
                + "开始时间: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()) + "\n" + getVideoInfo(inputPath) + "\n");
        pb_compress.setVisibility(View.VISIBLE);
        startTime = System.currentTimeMillis();
        Util.writeFile(MainActivity.this, "Start at: " + new SimpleDateFormat("HH:mm:ss", getLocale()).format(new Date()));
    }

    private Locale getLocale() {
        Configuration config = getResources().getConfiguration();
        Locale sysLocale = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sysLocale = getSystemLocale(config);
        } else {
            sysLocale = getSystemLocaleLegacy(config);
        }

        return sysLocale;
    }

    @SuppressWarnings("deprecation")
    public static Locale getSystemLocaleLegacy(Configuration config) {
        return config.locale;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public static Locale getSystemLocale(Configuration config) {
        return config.getLocales().get(0);
    }


    public String getVideoInfo(String filePath) {
        String videoInfo = "";
        try {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(filePath);
            int bitrate = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
            retriever.release();
            MediaExtractor extractor = new MediaExtractor();
            extractor.setDataSource(filePath);
            MediaFormat format = extractor.getTrackFormat(VideoUtil.selectTrack(extractor, false));
            int frameRate = format.containsKey(MediaFormat.KEY_FRAME_RATE) ? format.getInteger(MediaFormat.KEY_FRAME_RATE) : -1;
            //   float aveFrameRate = VideoUtil.getAveFrameRate(filePath);
            int width = format.getInteger(MediaFormat.KEY_WIDTH);
            int height = format.getInteger(MediaFormat.KEY_HEIGHT);
            int rotation = format.containsKey(MediaFormat.KEY_ROTATION) ? format.getInteger(MediaFormat.KEY_ROTATION) : -1;
            long duration = format.containsKey(MediaFormat.KEY_DURATION) ? format.getLong(MediaFormat.KEY_DURATION) : -1;
            videoInfo = String.format(Locale.ENGLISH, "分辨率:%dX%d,帧率:%d,方向:%d,码率:%d,时长:%.1fs", width, height, frameRate, rotation, bitrate,
                    duration / 1000f / 1000f);
            extractor.release();
            oriWidth = width;
            oriHeight = height;
            this.oriBitrate = bitrate;
            oriFrameRate = frameRate;
            this.videTime = duration / 1000f / 1000f;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return videoInfo;
    }

    public class Wang extends Binder {


    }
}
